/**
 * 统计子树的不同颜色的数量，因为没有修改操作
 * 可以用启发式合并暴力统计，最后离线回答
 */
#include <bits/stdc++.h>
using namespace std;

#include <bits/extc++.h>
using namespace __gnu_pbds;

using llt = long long;

struct dsu_on_tree_t{

using value_t = int;
using answer_t = int;
using vi = vector<int>;

int Root;
vector<vi> G; // 树
vector<value_t> W; // 点权值

vector<answer_t> ans; // 答案

struct node_t{
    int size; // size
    int hson; // 重儿子
    int nid;
    int mdes; // 本子树全部在[nid, mdes]之中
};
vector<int> new2old; // dfs序到原树节点的编号
vector<node_t> Nodes;
int TimeStamp;

int NowAns;
vector<int> Cnt;

void init(int n){
    TimeStamp = 0;
    G.assign(n + 1, {});
    W.assign(n + 1, 0);
    Nodes.assign(n + 1, {0, 0, 0, 0});
    new2old.assign(n + 1, 0);
    ans.assign(n + 1, 0);

    // assert(0);
    Cnt.assign(n + 1, NowAns = 0);
}

/// 建单向边
void mkDiEdge(int a, int b){
    G[a].push_back(b);
}
/// 建双向边
void mkBiEdge(int a, int b){
    mkDiEdge(a, b); mkDiEdge(b, a);
}

/// 递归找重边
void _dfsHeavyEdge(int u, int p){
    auto & n = Nodes[u];
    n.size = 1;
    new2old[n.nid = ++TimeStamp] = u;

    for(auto v : G[u]){
        if(v == p) continue;
        _dfsHeavyEdge(v, u);
        n.size += Nodes[v].size;
        if(Nodes[n.hson].size < Nodes[v].size) n.hson = v;
    }

    n.mdes = TimeStamp;
    return;
}

void _dfs(int u, int p, bool keep){
    const auto & node = Nodes[u];
    /// 轻儿子
    for(int v : G[u]){
        if(v == p or v == node.hson) continue;
        
        _dfs(v, u, false);
    }
    /// 重儿子
    if(node.hson) _dfs(node.hson, u, true);

    _count(u, p); // 统计非重儿子
    _answer(u); // 记录答案

    if(not keep) _clean(u); // 清空u子树对答案的贡献
    return;
}

void _count(int u, int p){
    const auto & node = Nodes[u];
    __insert(u);
    for(auto v : G[u]){
        if(v == p or v == node.hson) continue;
        for(int i=Nodes[v].nid,e=Nodes[v].mdes;i<=e;++i){
            __insert(new2old[i]);
        }
    }
    return;
}

void _clean(int u){
    for(int i=Nodes[u].nid,e=Nodes[u].mdes;i<=e;++i){
        __remove(new2old[i]);
    }
    // assert(0);
}

void __insert(int u){
    // assert(0);
    if(1 == ++Cnt[W[u]]) ++NowAns;
}

void __remove(int u){
    // assert(0);
    if(0 == --Cnt[W[u]]) --NowAns;
}

void _answer(int u){
    // assert(0);
    ans[u] = NowAns;
}

void run(int rt){
    Root = rt;
    _dfsHeavyEdge(Root, 0);
    _dfs(Root, 0, true);
    return;
}

};


dsu_on_tree_t Dsu;

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(0);
    int n; cin >> n;
    Dsu.init(n);
    for(int a,b,i=1;i<n;++i){
        cin >> a >> b;
        Dsu.mkBiEdge(a, b);
    }
    for(int i=1;i<=n;++i) cin >> Dsu.W[i];
    Dsu.run(1);
    int q; cin >> q;
    for(int r,i=0;i<q;++i){
        cin >> r;
        cout << Dsu.ans[r] << endl;
    }
    return 0;
}
